home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 13372 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  2.5 KB

  1. Path: max.tiac.net!craigm
  2. From: craigm@max.tiac.net (Craig Mattson)
  3. Newsgroups: comp.lang.c
  4. Subject: Intraprocess piping into an array
  5. Date: 6 Apr 1996 22:26:01 GMT
  6. Organization: The Internet Access Company
  7. Message-ID: <4k6r1p$eoh@news.tiac.net>
  8. NNTP-Posting-Host: max.tiac.net
  9.  
  10. I'd like to pipe stdout into an array so I can process it before
  11. it actually gets printed.  However, I don't want to fork a process
  12. just to read the array as it's being output.  Here's what I've been
  13. trying to do, which works until the output gets too large:
  14.  
  15.  
  16.     int pipefds[ 2 ];
  17.     int real_stdout;
  18.     char stdout_buf[ HUGE_BUFFER ];
  19.     char output_buffer[ 1024 ];
  20.     FILE *fp;
  21.  
  22.     int pipefds[2];
  23.     if( pipe(pipefds) <0)  {
  24.         perror( "pipe" );
  25.         exit( 1 );
  26.     }
  27.  
  28.     int real_stdout = dup( 1 );
  29.     close( 1 );
  30.     dup( pipefds[0] );
  31.     close( pipefds[0] );
  32.  
  33.     /*
  34.          * create a huge buffer for the new stdout so fputs(,stdout) doesn't
  35.      * block when trying to write more than the standard buffer size
  36.      */
  37.     setvbuf( stdout, stdout_buf, _IOFBF, MAX_HTML_LENGTH );
  38.  
  39.     /*
  40.      * call stuff that writes to stdout here (e.g. printf(), fputs() )
  41.      */
  42.  
  43.     /*
  44.      * now set stdout back to its real output
  45.      */
  46.     fflush( stdout );                      /* Here's my problem */
  47.     close( 1 );
  48.     dup( real_stdout );
  49.     close( real_stdout );
  50.     fp = fdopen( pipefds[1], "r" );
  51.     
  52.     /*
  53.      * read from fp to do whatever
  54.      */
  55.  
  56.     fclose( fp );
  57.  
  58. The problem is that the fflush() tries to flush the _whole_ buffer,
  59. which is often too large for the standard buffer size for the read end
  60. of the pipe.  So it blocks until the other end of the pipe clears out
  61. some space, which of course doesn't happen because there's no other
  62. process involved.
  63.  
  64. I tried calling fdopen() for the read side before calling fflush() and
  65. using setvbuf() to make the read buffer bigger like I do for the write
  66. side.  This doesn't seem to solve the problem.
  67.  
  68. I don't really need to use the stdio library to read from the pipe.  Is
  69. it safe to just examine the stdout_buf array I'm using directly?  If so,
  70. how do I just kill the pipe so that when I exit() it doesn't try to
  71. close it for me and end up blocking there?  Alternatively, can I increase
  72. the size of the buffer used by the file descriptors created by pipe()?
  73. Can I somehow flush just part of the array at a time?
  74.  
  75. I'm certain other people have thought about this problem, and there may
  76. be some standard approach for how to do this.  Any education you could
  77. offer me would be greatly appreciated.  Email is better for me that the
  78. newsgroup, but I should get it either way.
  79.  
  80. Thanks, 
  81.  
  82. Craig
  83.  
  84.  
  85.